<script setup lang="ts">
import type { RuleObject } from 'ant-design-vue/es/form';
import { computed, ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { cloneDeep } from '@vben/utils';
import {
  Form,
  FormItem,
  Input,
  InputNumber,
  TimePicker,
  CheckboxGroup,
  Divider,
  Space,
  Typography,
} from 'ant-design-vue';
import { useBeforeCloseDiff } from '#/utils/popup';
import type {
  DietConfigForm,
  PlanConfigVO,
} from '#/api/healthPlan/config/planConfig/model';
import {
  planConfigInfo,
  planConfigUpdate,
} from '#/api/healthPlan/config/planConfig';

const emit = defineEmits<{ reload: [] }>();

const title = '饮食方案配置';
const taskData = ref<PlanConfigVO | null>(null);
const matchedUserCount = ref(0);

// 定义表单的默认值
const getDefaultValues = (): DietConfigForm => ({
  genders: [],
  ageRange: [undefined, undefined],
  bmiRange: [undefined, undefined],
  totalCalories: '自动计算',
  carbohydrateRatio: 50,
  proteinRatio: 30,
  fatRatio: 20,
  reminderTime: undefined,
});

const formData = ref<DietConfigForm>(getDefaultValues());

// --- 动态计算和校验 ---

// 监听营养素比例，确保总和为100
watch(
  () => [
    formData.value.carbohydrateRatio,
    formData.value.proteinRatio,
    formData.value.fatRatio,
  ],
  () => {
    const { carbohydrateRatio, proteinRatio, fatRatio } = formData.value;
    const total =
      (carbohydrateRatio || 0) + (proteinRatio || 0) + (fatRatio || 0);
    if (total !== 100) {
      // 可以在这里给出提示，或者在formRules中处理
    }
  },
);

// 监听适用人群设置，动态获取匹配人数
watch(
  () => [
    formData.value.genders,
    formData.value.ageRange,
    formData.value.bmiRange,
  ],
  async () => {
    if (
      formData.value.genders.length ||
      formData.value.ageRange[0] ||
      formData.value.bmiRange[0]
    ) {
      // const count = await getMatchedUserCount({ ...formData.value });
      // matchedUserCount.value = count;
    }
  },
  { deep: true },
);

const formRules = computed<Partial<Record<keyof DietConfigForm, RuleObject[]>>>(
  () => {
    const validateRatio = async () => {
      const { carbohydrateRatio, proteinRatio, fatRatio } = formData.value;
      const total =
        (carbohydrateRatio || 0) + (proteinRatio || 0) + (fatRatio || 0);
      if (total !== 100) {
        return Promise.reject('碳水、蛋白质和脂肪的比例总和必须等于100%');
      }
      return Promise.resolve();
    };

    return {
      genders: [{ required: true, message: '请选择适用性别' }],
      ageRange: [
        { required: true, message: '请输入年龄区间' },
        {
          type: 'array',
          validator: async (_, value) =>
            value[0] && value[1]
              ? Promise.resolve()
              : Promise.reject('请输入年龄区间'),
        },
      ],
      bmiRange: [
        { required: true, message: '请输入BMI区间' },
        {
          type: 'array',
          validator: async (_, value) =>
            value[0] && value[1]
              ? Promise.resolve()
              : Promise.reject('请输入BMI区间'),
        },
      ],
      carbohydrateRatio: [
        { required: true, message: '请输入碳水化合物比例' },
        { validator: validateRatio },
      ],
      proteinRatio: [
        { required: true, message: '请输入蛋白质比例' },
        { validator: validateRatio },
      ],
      fatRatio: [
        { required: true, message: '请输入脂肪比例' },
        { validator: validateRatio },
      ],
      reminderTime: [{ required: true, message: '请选择提醒时间' }],
    };
  },
);

const { validate, validateInfos, resetFields } = Form.useForm(
  formData,
  formRules,
);

// --- 弹窗逻辑 ---

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: () => JSON.stringify(formData.value),
    currentGetter: () => JSON.stringify(formData.value),
  },
);

const [BasicModal, modalApi] = useVbenModal({
  class: 'w-[700px]',
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  onOpenChange: async (isOpen) => {
    if (!isOpen) return;
    modalApi.modalLoading(true);
    const record = modalApi.getData() as PlanConfigVO;
    taskData.value = await planConfigInfo(record.id);
    if (taskData.value && taskData.value.taskConfig) {
      formData.value = { ...getDefaultValues(), ...taskData.value.taskConfig };
    }
    await markInitialized();
    modalApi.modalLoading(false);
  },
});

async function handleConfirm() {
  try {
    modalApi.modalLoading(true);
    await validate();
    const dataToSubmit = {
      ...taskData.value,
      taskConfig: cloneDeep(formData.value),
      triggerConfig: {
        // 每日触发
        dailyTrigger: true,
      },
    };
    await planConfigUpdate(dataToSubmit);
    resetInitialized();
    emit('reload');
    modalApi.close();
  } catch (error) {
    console.error(error);
  } finally {
    modalApi.modalLoading(false);
  }
}

function handleClosed() {
  resetFields();
  formData.value = getDefaultValues();
  resetInitialized();
}
</script>

<template>
  <BasicModal :title="title">
    <Form :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
      <Divider>适用人群设置</Divider>
      <FormItem label="适用性别" v-bind="validateInfos.genders">
        <CheckboxGroup
          v-model:value="formData.genders"
          :options="[
            { label: '男', value: 'MALE' },
            { label: '女', value: 'FEMALE' },
          ]"
        />
      </FormItem>
      <FormItem label="年龄区间" v-bind="validateInfos.ageRange">
        <Space>
          <InputNumber v-model:value="formData.ageRange[0]" :min="1" />
          <span>-</span>
          <InputNumber
            v-model:value="formData.ageRange[1]"
            :min="formData.ageRange[0] || 1"
          />
        </Space>
      </FormItem>
      <FormItem label="BMI区间" v-bind="validateInfos.bmiRange">
        <Space>
          <InputNumber v-model:value="formData.bmiRange[0]" :min="1" />
          <span>-</span>
          <InputNumber
            v-model:value="formData.bmiRange[1]"
            :min="formData.bmiRange[0] || 1"
          />
        </Space>
      </FormItem>
      <FormItem label="当前匹配人数">
        <Typography.Text type="danger" class="font-bold"
          >{{ matchedUserCount }} 人</Typography.Text
        >
      </FormItem>

      <Divider>每日摄入配置</Divider>
      <FormItem label="总热量目标">
        <Input :value="formData.totalCalories" disabled addon-after="kcal" />
      </FormItem>
      <FormItem label="营养素比例" required>
        <Space direction="vertical">
          <FormItem v-bind="validateInfos.carbohydrateRatio" class="!mb-0">
            <Space.Compact>
              <Input value="碳水化合物" readonly style="width: 100px" />
              <InputNumber v-model:value="formData.carbohydrateRatio" />
              <Input value="%" readonly style="width: 50px" />
            </Space.Compact>
          </FormItem>
          <FormItem v-bind="validateInfos.proteinRatio" class="!mb-0">
            <Space.Compact>
              <Input value="蛋白质" readonly style="width: 100px" />
              <InputNumber v-model:value="formData.proteinRatio" />
              <Input value="%" readonly style="width: 50px" />
            </Space.Compact>
          </FormItem>
          <FormItem v-bind="validateInfos.fatRatio" class="!mb-0">
            <Space.Compact>
              <Input value="脂肪" readonly style="width: 100px" />
              <InputNumber v-model:value="formData.fatRatio" />
              <Input value="%" readonly style="width: 50px" />
            </Space.Compact>
          </FormItem>
        </Space>
      </FormItem>
      <Divider />
      <FormItem label="提醒时间" v-bind="validateInfos.reminderTime">
        <TimePicker
          v-model:value="formData.reminderTime"
          class="w-full"
          format="HH:mm:ss"
          value-format="HH:mm:ss"
        />
      </FormItem>
    </Form>
  </BasicModal>
</template>
